#!/usr/bin/env python
# -*- coding:utf-8 -*-

# Author: lookfuyao@gmail.com
# Email: lookfuyao@gmail.com
# Version： V1.0.1
# Description: Auto Patch Tools, Use to patch Mtk release patch like alps alps_pre

import argparse
import os
import logging
import time
import shutil

from common.RepoUtils import RepoHelper, repo_clean_all_change
from common.langconv import Converter
from common.Tools import generate_path_use_diff, apply_patch_use_patch
from common.ShellUtils import shell_cmd

# for commit Jira Id begin
DEF_COMMIT_JIRA_ID = "PCAAO-1924"
# for commit Jira Id end

# for logging begin
LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
DATE_FORMAT = "%m/%d/%Y %H:%M:%S %p"
# for logging end

# for PATCH TAG begin
DEF_DESCRIPTION_FILE_NAME = 'patch_list.txt'
DEF_TAG_PATCH_TYPE = 'Patch Type:'
DEF_TAG_CR_ID = 'CR ID:'
DEF_TAG_SEVERITY = 'Severity:'
DEF_TAG_DESCRIPTION = 'Description:'
DEF_TAG_ASSOCIATED_FILES = 'Associated Files:'
# for PATCH TAG end

# for PATCH TAG begin
DEF_PRE_DIR = 'alps_pre'
DEF_DIR = 'alps'


# for PATCH TAG end
# https://blog.csdn.net/wds2006sdo/article/details/53583367
def traditional_2_simplified(sentence):
    sentence = Converter('zh-hans').convert(sentence)
    return sentence


def parse_all_patches(patch_dir):
    patch_list_path = os.path.join(patch_dir, DEF_DESCRIPTION_FILE_NAME)
    if os.path.exists(patch_list_path):
        with open(patch_list_path) as f:
            all_patches = []
            all_lines = f.readlines()
            item = None
            cur_tag = None
            for line in all_lines:
                line = line.strip()
                logging.debug("+++++++++++++++++++++++++++++++++++++++++++++++")
                logging.debug("line=%s  len(line)=%s" % (line, len(line)))
                if not line:
                    continue
                if len(line) <= 0:
                    continue
                if line.startswith('#'):
                    continue
                if line == DEF_TAG_PATCH_TYPE:
                    if item:
                        all_patches.append(item)
                    logging.debug("Find TAG---> %s" % DEF_TAG_PATCH_TYPE)
                    cur_tag = DEF_TAG_PATCH_TYPE
                    item = {}
                elif line == DEF_TAG_CR_ID:
                    logging.debug("Find TAG---> %s" % DEF_TAG_CR_ID)
                    cur_tag = DEF_TAG_CR_ID
                elif line == DEF_TAG_SEVERITY:
                    logging.debug("Find TAG---> %s" % DEF_TAG_SEVERITY)
                    cur_tag = DEF_TAG_SEVERITY
                elif line == DEF_TAG_DESCRIPTION:
                    logging.debug("Find TAG---> %s" % DEF_TAG_DESCRIPTION)
                    cur_tag = DEF_TAG_DESCRIPTION
                elif line == DEF_TAG_ASSOCIATED_FILES:
                    logging.debug("Find TAG---> %s" % DEF_TAG_ASSOCIATED_FILES)
                    cur_tag = DEF_TAG_ASSOCIATED_FILES
                else:
                    logging.debug("cur_tag =%s" % cur_tag)
                    if cur_tag:
                        if cur_tag in item:
                            line = Converter('zh-hans').convert(line.decode('utf-8'))
                            line = line.encode('utf-8')
                            tmp = item[cur_tag]
                            tmp.append(line)
                            item[cur_tag] = tmp
                        else:
                            item[cur_tag] = [line]
                logging.debug("----------------------------------------")
            # add Last item here
            if item:
                all_patches.append(item)
            logging.debug("********************************************Patch Count=%s" % len(all_patches))
            logging.debug(all_patches)
            return all_patches
    return None


# ./ToolMtkFolderPatch.py -s "/home/android/Desktop/ALPS04245600" -d "/home/android/Platform/MT6739_9/k510" -j PCAAO-1924 -c True'
if __name__ == '__main__':
    _parser = argparse.ArgumentParser(description='Auto Patch Tool for MTK Folder compare patch')
    _parser.add_argument("-d", "--dst_dir", required=True, help="Dst Project dir")
    _parser.add_argument("-s", "--patch_dir", required=True, help="Mtk Folder patch dir")
    _parser.add_argument("-j", "--jira_id", help="Jira Id to Associated")
    _parser.add_argument("-c", "--clean", default=True, help="If need clean all change, include commits, modify etc...")
    _args = _parser.parse_args()

    _work_path = os.path.dirname(os.path.realpath(__file__))
    _now = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime(time.time()))
    _log_file_name = os.path.join(_work_path, "logs", 'log' + _now + ".log")
    if not os.path.exists(os.path.dirname(_log_file_name)):
        os.mkdir(os.path.dirname(_log_file_name))
    logging.basicConfig(level=logging.DEBUG,
                        format=LOG_FORMAT,
                        datefmt=DATE_FORMAT,
                        filename=_log_file_name
                        )

    if not os.path.exists(_args.dst_dir):
        logging.error("Dst Project dir not exist")
        exit(1)

    _repoHelper = RepoHelper(_args.dst_dir)
    _all_gits = _repoHelper.get_gits()
    if not _all_gits or len(_all_gits) <= 0:
        logging.error("Cannot get gits from project dir %s" % _args.dst_dir)
        exit(2)
    logging.debug(_all_gits)

    if not os.path.exists(_args.patch_dir):
        logging.error("Patch dir not exist: %s" % _args.patch_dir)
        exit(3)
    _all_patches = parse_all_patches(_args.patch_dir)
    if not _all_patches or len(_all_patches) <= 0:
        logging.error("Cannot find any Patch at: %s" % _args.patch_dir)
        exit(3)

    if _args.clean:
        repo_clean_all_change(_args.dst_dir)
        # shell_cmd("cd %s; repo --no-pager forall -c 'git reset --hard K510BG_9.0_WIK_TH_04'" % _args.dst_dir)

    _temp_dir = os.path.join(_args.patch_dir, "temp")
    if os.path.exists(_temp_dir):
        shutil.rmtree(_temp_dir)
    if not os.path.exists(_temp_dir):
        os.mkdir(_temp_dir)

    if not _args.jira_id:
        _jira_id = DEF_COMMIT_JIRA_ID
    else:
        _jira_id = _args.jira_id

    _tmp_patch = os.path.join(_temp_dir, "tmp_patch")

    _alps_dir = os.path.join(_args.patch_dir, "alps")
    _alps_pre_dir = os.path.join(_args.patch_dir, "alps_pre")

    _all_push_gits = []

    _index = 0
    for _patch in _all_patches:
        logging.debug("%s---------------------------------------->" % _index)
        logging.debug("Handle CR ID: %s" % _patch[DEF_TAG_CR_ID])
        _index = _index + 1

        _tmp_alps_dir = os.path.join(_temp_dir, "alps")
        if os.path.exists(_tmp_alps_dir):
            shutil.rmtree(_tmp_alps_dir)
        _tmp_alps_pre_dir = os.path.join(_temp_dir, "alps_pre")
        if os.path.exists(_tmp_alps_pre_dir):
            shutil.rmtree(_tmp_alps_pre_dir)

        _base_git_vec = []

        _files = _patch[DEF_TAG_ASSOCIATED_FILES]
        for _file in _files:
            _git = _repoHelper.get_git_by_path(_file)
            if not _git:
                logging.error("ERROR: Cannot find git for %s" % _file)
                continue
            if _git not in _base_git_vec:
                _base_git_vec.append(_git)

            _tmp = os.path.dirname(os.path.join(_tmp_alps_dir, _file))
            if not os.path.exists(_tmp):
                os.makedirs(_tmp)

            if os.path.exists(os.path.join(_alps_dir, _file)):
                shutil.copy2(os.path.join(_alps_dir, _file), os.path.join(_tmp_alps_dir, _file))

            _tmp = os.path.dirname(os.path.join(_tmp_alps_pre_dir, _file))
            if not os.path.exists(_tmp):
                os.makedirs(_tmp)

            if os.path.exists(os.path.join(_alps_pre_dir, _file)):
                shutil.copy2(os.path.join(_alps_pre_dir, _file), os.path.join(_tmp_alps_pre_dir, _file))

            logging.debug("find %s for %s" % (_git, _file))

        #  _cmd = "cd %s; diff -Naur %s %s > %s" % (_temp_dir, _tmp_alps_pre_dir, _tmp_alps_dir, _tmp_patch)
        generate_path_use_diff(_temp_dir, "alps_pre", "alps", _tmp_patch)
        apply_patch_use_patch(_repoHelper.get_android_abs_dir(), _tmp_patch, 1)

        for _base_git in _base_git_vec:
            if _base_git not in _all_push_gits:
                _all_push_gits.append(_base_git)
            _tmp_git = os.path.join(_repoHelper.get_android_abs_dir(), _base_git)
            if len(_patch[DEF_TAG_DESCRIPTION]) >= 1:
                _commit_str = _patch[DEF_TAG_DESCRIPTION][0]
            else:
                _commit_str = ""
            _commit = "%s-%s-%s" % (_patch[DEF_TAG_CR_ID], _patch[DEF_TAG_PATCH_TYPE], _commit_str)
            _cmd = "cd %s; git add -A; git commit -m \"<REQ><%s><%s>\"" % (_tmp_git, _jira_id, _commit)
            _ret = shell_cmd(_cmd)
            if _ret != 0:
                logging.error("Error(%s): patch @%s --->%s" % (_ret, _tmp_git, _commit))
            else:
                logging.debug("patch @%s --->%s" % (_tmp_git, _commit))
        logging.debug("<----------------------------------------\n")

    print("**********************************************************")
    for _tmp in range(0, len(_all_push_gits)):
        print("[%s]-->%s" % (_tmp, _all_push_gits[_tmp]))
    print("##########################################################")
